﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ALDIOrganizer
{
    [Serializable]
    public class Theme
    {
        public const int Blank = 0;

        public const int TotalHours = 1;
        public const int Employee = 2;

        public const int Shift = 3;
        public const int Holidays = 4;
        public const int Request = 5;
        public const int NotEmployed = 6;
        
        public const int AnyNotes = 7;

        public const int Past = 8;
        public const int Today = 9;

        public const int Inventory = 10;
        public const int Shut = 11;
        public const int BankHoliday = 12;

        public const int RequestViolation = 13;
        public const int TemplateMismatch = 14;
        public const int WorkingHrsMismatch = 15;                
        public const int MaxValue = 15;

        // Colours are nullable - if HasValue = false, default colour is used instead.
        private Style[] Colours;

        public static bool OutOfRange(int i)
        {
            return ((i<0)||(i>MaxValue));
        }

        public static Style MixColours(Style[] colours)
        {
            if (colours.Length == 1)
            {
                return colours[0];
            }
            var result = new Style();
            int backs = 0;
            int fores = 0;
            int Fr = 0; int Br = 0;
            int Fg = 0; int Bg = 0;
            int Fb = 0; int Bb = 0;
                        
            foreach (Style next in colours)
            {
                if (next.ForeColour.HasValue)
                {
                    Fr += next.ForeColour.Value.R;
                    Fg += next.ForeColour.Value.G;
                    Fb += next.ForeColour.Value.B;
                    fores += 1;
                }
                if (!next.BackColour.HasValue)
                {
                    continue;
                }
                Br += next.BackColour.Value.R;
                Bg += next.BackColour.Value.G;
                Bb += next.BackColour.Value.B;
                backs += 1;
            }

            if (fores > 0)
            {
                result.ForeColour = Color.FromArgb(
                    Fr / fores,
                    Fg / fores,
                    Fb / fores);
            }
            if (backs > 0)
            {
                result.BackColour = Color.FromArgb(
                    Br / backs,
                    Bg / backs,
                    Bb / backs);
            }
            return result;
        }        

        public Theme()
        {
            this.Colours = new Style[MaxValue+1];
        }

        public Style GetColour(int which)
        {

            if (Theme.OutOfRange(which))
            {
                throw new ArgumentException("There is no colour number " + which.ToString() + " in ColourScheme");
            }

            var local_one = Colours[which];
            var default_one = StandardColourTheme.GetColour(which);
            var result = new Style(local_one.BackColour.HasValue ? local_one.BackColour : default_one.BackColour,
                local_one.ForeColour.HasValue ? local_one.ForeColour : default_one.ForeColour,
                local_one.Bold.HasValue ? local_one.Bold : default_one.Bold);

            return result;
        }
    }

    public static class StandardColourTheme
    {
        private static Style[] defaultColours;        

        public static Style GetColour(int which)
        {
            if (Theme.OutOfRange(which))
            {
                return defaultColours[Theme.Blank];
            }
            return defaultColours[which];         
        }
                
        static StandardColourTheme()
        {
            defaultColours = new Style[Theme.MaxValue + 1];

            defaultColours[Theme.Blank] = new Style(
                Settings.Default.COLOURBack_Blank,
                Settings.Default.COLOURForeground_Blank,
                false);
            defaultColours[Theme.TotalHours] = new Style(
                Settings.Default.COLOURBack_TotalHours,
                Settings.Default.COLOURForeground_TotalHours,
                true);
            defaultColours[Theme.Employee] = new Style(
                Settings.Default.COLOURBack_Employee,
                Settings.Default.COLOURForeground_Employee,
                true);
            defaultColours[Theme.Shift] = new Style(
                Settings.Default.COLOURBack_Shift,
                Settings.Default.COLOURForeground_Shift,
                true);
            defaultColours[Theme.Holidays] = new Style(
                Settings.Default.COLOURBack_Holidays,
                Settings.Default.COLOURForeground_Holidays,
                true);
            defaultColours[Theme.Request] = new Style(
                Settings.Default.COLOURBack_Request,
                Settings.Default.COLOURForeground_Request,
                true);
            defaultColours[Theme.NotEmployed] = new Style(
                Settings.Default.COLOURBack_NotEmployed,
                Settings.Default.COLOURForeground_NotEmployed,
                true);
            defaultColours[Theme.AnyNotes] = new Style(
                Settings.Default.COLOURBack_AnyNotes,
                Settings.Default.COLOURForeground_AnyNotes, true);
            defaultColours[Theme.Past] = new Style(
                Settings.Default.COLOURBack_Past,
                Settings.Default.COLOURForeground_Past,
                null);
            defaultColours[Theme.Today] = new Style(
                Settings.Default.COLOURBack_Today,
                Settings.Default.COLOURForeground_Today,
                null);
            defaultColours[Theme.Inventory] = new Style(
                Settings.Default.COLOURBack_Inventory,
                Settings.Default.COLOURForeground_Inventory,
                null);
            defaultColours[Theme.Shut] = new Style(
                Settings.Default.COLOURBack_Shut,
                Settings.Default.COLOURForeground_Shut,
                null);
            defaultColours[Theme.BankHoliday] = new Style(
                Settings.Default.COLOURBack_BankHoliday,
                Settings.Default.COLOURForeground_BankHoliday,
                null);
            defaultColours[Theme.RequestViolation] = new Style(
                Settings.Default.COLOURBack_RequestViolation,
                Settings.Default.COLOURForeground_RequestViolation,
                null);
            defaultColours[Theme.TemplateMismatch] = new Style(
                Settings.Default.COLOURBack_TemplateMismatch,
                Settings.Default.COLOURForeground_TemplateMismatch,
                null);
            defaultColours[Theme.WorkingHrsMismatch] = new Style(
                Settings.Default.COLOURBack_WorkingHrsMismatch,
                Settings.Default.COLOURForeground_WorkingHrsMismatch,
                null);            
        }       
        
    }

    [Serializable]
    public class CachedStyle
    {
        public Color Backcolor;
        public Color Forecolor;
        public bool Bold;
    }
}
